package com.ahdms.es.util;

import com.ahdms.es.bean.enums.VerifyCertCode;
import com.ahdms.es.exceptions.InvalidSignedValueException;
import com.ahdms.es.gm.constant.IKIObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.ByteArrayInputStream;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.cert.Certificate;
import java.util.Objects;

/**
 * 标准的签名验签工具
 *
 * @author qinxiang
 * @date 2021-04-13 11:34
 */
public class GeneralSignatureUtils {

    /**
     * 验签
     *
     * @param certDER    证书的DER编码
     * @param algorithm  签名算法
     * @param sourceData 原文
     * @param signData   签名值
     * @return
     * @throws Exception
     */
    public static boolean verifySign(byte[] certDER, String algorithm, byte[] sourceData, byte[] signData) throws Exception {
        Signature sg = Signature.getInstance(algorithm, new BouncyCastleProvider());
        Certificate signCert = (new CertificateFactory()).engineGenerateCertificate(new ByteArrayInputStream(certDER));
        sg.initVerify(signCert);
        sg.update(sourceData);
        return sg.verify(signData);
    }

    public static boolean verifySign(org.bouncycastle.asn1.x509.Certificate x509Cert, String algorithm, byte[] sourceData, byte[] signData) {
        if (Objects.equals(IKIObjectIdentifiers.sm2_with_sm3.getId(), algorithm)) {
            boolean verifySignResult = SM2Utils.verifySign(x509Cert, sourceData, signData);
            return verifySignResult;
        } else {
            throw new IllegalArgumentException(VerifyCertCode.CERT_Algorithm_Invalid.getMessage());
        }
    }

    public static boolean verifySign(org.bouncycastle.asn1.x509.Certificate x509Cert, AlgorithmIdentifier algorithm, byte[] sourceData, byte[] signData) {
        return verifySign(x509Cert, algorithm.getAlgorithm().getId(), sourceData, signData);
    }

    public static void main(String[] args) {
        org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(NioUtils.fileToBytes(""));
    }

}
